package com.codeoss.framework.view.parser;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.codeoss.framework.data.metadata.Column;
import com.codeoss.framework.data.metadata.Table;
import com.codeoss.framework.data.store.ITableStore;
import com.codeoss.framework.expression.Expression;
import com.codeoss.framework.expression.ExpressionUtil;
import com.codeoss.framework.util.LookupInfo;
import com.codeoss.framework.util.StringUtils;
import com.codeoss.framework.view.component.Component;
import com.codeoss.framework.view.component.Search;
import com.codeoss.framework.view.datasource.DataSourceConfig;
import com.codeoss.framework.view.util.DataSourceUtil;
import com.codeoss.framework.view.util.ViewUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

@Service
public class SearchParser extends AbstractComponentParser {
	@Autowired
	private ITableStore tableStore;
	@Autowired
	private DataSourceUtil dataSourceUtil;
	@Autowired
	private ViewUtil viewUtil;
	protected void setAttributes(IParseContext parseContext, ObjectNode objectNode, Component component) {
		super.setAttributes(parseContext, objectNode, component);
		Search search = (Search) component;
		String labelExpression = objectNode.get("labelExpression").asText();
		JsonNode jsonNode=objectNode.get("col");
		if(jsonNode!=null) {
			int col=objectNode.get("col").asInt();
			search.setCol(col);
		}
	
		jsonNode=objectNode.get("fieldcol");
		if(jsonNode!=null) {
			int fieldCol=objectNode.get("fieldcol").asInt();
			search.setFieldCol(fieldCol);
		}
		if (!StringUtils.isEmpty(labelExpression)) {
			Expression expression = ExpressionUtil.convertLabelToExpression(labelExpression,Expression.EXPRESSION_TYPE_JAVASCRIPT);
			search.setLabelExpression(expression);
		}
		
		ObjectNode propertyMapNode=(ObjectNode)objectNode.get("propertyMap");
		if(propertyMapNode!=null) {
			jsonNode=propertyMapNode.get("dataSource");
			if(jsonNode!=null) {
				String dataSource=propertyMapNode.get("dataSource").asText();
				search.setDataSource(dataSource);
			}
			jsonNode=propertyMapNode.get("dataField");
			if(jsonNode!=null) {
				String dataField=propertyMapNode.get("dataField").asText();
				search.setDataField(dataField);
				
				DataSourceConfig dataSourceConfig=dataSourceUtil.getDataSourceConfigById(parseContext.getPage(), search.getDataSource());
				Table table= tableStore.get(dataSourceConfig.getTableName());
				Column column=table.getColumnByColumnName(dataField);
				String requiredExpression=column.getRequiredExpression();
				if(!StringUtils.isEmpty(requiredExpression)) {
					Expression expression=ExpressionUtil.convertToExpression(requiredExpression, Expression.EXPRESSION_TYPE_JAVASCRIPT);
					search.setRequiredExpression(expression);
				}
				String readOnlyExpression=column.getReadOnlyExpression();
				if(!viewUtil.isSearchPage(parseContext.getPage()) &&!StringUtils.isEmpty(readOnlyExpression)) {
					Expression expression=ExpressionUtil.convertToExpression(readOnlyExpression, Expression.EXPRESSION_TYPE_JAVASCRIPT);
					search.setReadOnlyExpression(expression);
				}
				String defaultValueExpression=column.getDefaultValueExpression();
				if(!StringUtils.isEmpty(defaultValueExpression)) {
					Expression expression=ExpressionUtil.convertToExpression(defaultValueExpression, Expression.EXPRESSION_TYPE_JAVASCRIPT);
					search.setDefaultValueExpression(expression);
				}
				
				search.setDataType(column.getDataType());
				
				jsonNode=propertyMapNode.get("varName");
				String varName="";
				if(jsonNode==null||StringUtils.isEmpty(jsonNode.asText())) {
					if(!StringUtils.isEmpty(search.getDataSource()) && !StringUtils.isEmpty(search.getDataField())) {
						varName=table.getTableName()+"_"+search.getDataField();
					}
				}else {
					varName=propertyMapNode.get("varName").asText();
				}
				search.setVarName(varName);
			}
			
			
			jsonNode=propertyMapNode.get("pageCode");
			if(jsonNode!=null) {
				String pageCode=propertyMapNode.get("pageCode").asText();
				search.setPageCode(pageCode);
			}
			
			jsonNode=propertyMapNode.get("onChangeExpression");
			if(jsonNode!=null) {
				String onChangeExpression=jsonNode.asText();
				if(!StringUtils.isEmpty(onChangeExpression)) {
					String expressionType=Expression.EXPRESSION_TYPE_JAVASCRIPT;
					if(onChangeExpression.startsWith("@")) {
						expressionType=Expression.EXPRESSION_TYPE_SPRING;
					}
					Expression expression=ExpressionUtil.convertToExpression(onChangeExpression,expressionType);
					search.setOnChangeExpression(expression);
				}
			}
		}
		jsonNode= objectNode.get("noLabel");
		if(jsonNode!=null) {
			search.setNoLabel(jsonNode.asBoolean());
		}
	}
	
	public void afterPageParse(IParseContext parseContext,Component component) {
		Search search = (Search) component;
		 DataSourceConfig dataSourceConfig=dataSourceUtil.getDataSourceConfigById(parseContext.getPage(), search.getDataSource());
		 if(dataSourceConfig==null) {
			 return;
		 }
		 Table table= tableStore.get(dataSourceConfig.getTableName());
		 Column column=table.getColumnByColumnName(search.getDataField());
		 
		 if(column!=null) {
			 Expression requiredExpression=search.getRequiredExpression();
			 if(requiredExpression!=null) {
				 parseExpression(parseContext, component, requiredExpression, "required", false);
			 }
			 
			 Expression readonlyExpression=search.getReadOnlyExpression();
			 if(readonlyExpression!=null) {
				 parseExpression(parseContext, component, readonlyExpression, "readonly", true);
			 }
			 
			 Expression defaultValueExpression=search.getDefaultValueExpression();
			 if(defaultValueExpression!=null) {
				 parseExpression(parseContext, component, defaultValueExpression, "defaultValue", false);
			 }
			 
			 Expression visibleExpression=search.getVisibleExpression();
			 if(visibleExpression!=null) {
				 parseExpression(parseContext, component, visibleExpression, "visible", true);
			 }
			 LookupInfo lookupInfo=column.getLookupInfo();
			 if(lookupInfo!=null) {
				 LookupInfo newLookupInfo=lookupInfo.clone();
				 search.setLookupInfo(newLookupInfo);
				 
				 DataSourceConfig columnDataSourceConfig=newLookupInfo.getDataSourceConfig();
				 if(columnDataSourceConfig!=null) {
					 String daynamicWhereClause=columnDataSourceConfig.getDynamicWhereClause();
					 if(daynamicWhereClause!=null) {
						 Expression daynamicWhereClauseExpression=ExpressionUtil.convertToExpression(daynamicWhereClause, Expression.EXPRESSION_TYPE_JAVASCRIPT);
						 newLookupInfo.setDynamicWhereClauseExpression(daynamicWhereClauseExpression);
						 parseExpression(parseContext, component, daynamicWhereClauseExpression, "where", false);
					 }
				 }
			 }
		 }
		 super.afterPageParse(parseContext, component);
	}
	
	@Override
	protected Component createComponent(IParseContext parseContext, ObjectNode objectNode) {
		// TODO Auto-generated method stub
		return new Search();
	}

}
